<template>
  <div class="webgl-playground">
    <div class="playground-header">
      <h2>WebGL在线编辑器</h2>
      <div class="header-actions">
        <el-button type="primary" @click="runCode" :icon="VideoPlay">运行代码</el-button>
        <el-button @click="resetCode" :icon="RefreshRight">重置</el-button>
        <el-select v-model="selectedTemplate" @change="loadTemplate" placeholder="选择模板">
          <el-option
            v-for="option in templateOptions"
            :key="option.value"
            :label="option.label"
            :value="option.value"
          />
        </el-select>
      </div>
    </div>

    <div class="playground-content">
      <CodeEditor
        v-model:vertex-code="vertexShader"
        v-model:fragment-code="fragmentShader"
        v-model:js-code="jsCode"
        v-model:active-tab="activeTab"
      />

      <div class="preview-panel">
        <div class="preview-header">
          <h3>预览</h3>
          <el-button size="small" @click="handleClearCanvas">清空画布</el-button>
        </div>
        <div class="canvas-container">
          <canvas ref="canvasRef" width="600" height="600"></canvas>
        </div>
        
        <ConsolePanel :logs="consoleLogs" @clear="clearConsole" />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { VideoPlay, RefreshRight } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import CodeEditor from './components/CodeEditor.vue'
import ConsolePanel, { type ConsoleLog } from './components/ConsolePanel.vue'
import { templates, templateOptions } from './templates'
import { runWebGLCode, clearCanvas } from './utils/codeRunner'

// Refs
const canvasRef = ref<HTMLCanvasElement | null>(null)
const activeTab = ref('vertex')
const selectedTemplate = ref('line')

// 代码状态
const vertexShader = ref(templates.line.vertex)
const fragmentShader = ref(templates.line.fragment)
const jsCode = ref(templates.line.js)

// 控制台日志
const consoleLogs = ref<ConsoleLog[]>([])

// 添加日志
const addLog = (type: ConsoleLog['type'], message: string) => {
  consoleLogs.value.push({ type, message })
}

// 清空控制台
const clearConsole = () => {
  consoleLogs.value = []
}

// 清空画布
const handleClearCanvas = () => {
  if (!canvasRef.value) return
  if (clearCanvas(canvasRef.value)) {
    addLog('info', '画布已清空')
  }
}

// 运行代码
const runCode = () => {
  try {
    clearConsole()
    addLog('info', '开始运行代码...')

    if (!canvasRef.value) {
      throw new Error('Canvas元素未找到')
    }

    runWebGLCode({
      canvas: canvasRef.value,
      vertexShaderSource: vertexShader.value,
      fragmentShaderSource: fragmentShader.value,
      jsCode: jsCode.value,
      onLog: addLog
    })

    ElMessage.success('代码执行成功')
  } catch (error: any) {
    addLog('error', error.message || '代码执行错误')
    ElMessage.error('代码执行失败: ' + error.message)
  }
}

// 重置代码
const resetCode = () => {
  loadTemplate()
  clearConsole()
  handleClearCanvas()
  ElMessage.success('代码已重置')
}

// 加载模板
const loadTemplate = () => {
  const template = templates[selectedTemplate.value as keyof typeof templates]
  if (template) {
    vertexShader.value = template.vertex
    fragmentShader.value = template.fragment
    jsCode.value = template.js
  }
}

onMounted(() => {
  addLog('info', 'WebGL在线编辑器已就绪')
  addLog('info', '点击"运行代码"按钮执行您的代码')
})
</script>

<style lang="scss" scoped>
.webgl-playground {
  height: calc(100vh - 120px);
  display: flex;
  flex-direction: column;
  background-color: #fff;
  border-radius: 4px;
  overflow: hidden;

  .playground-header {
    padding: 20px;
    border-bottom: 1px solid #dcdfe6;
    display: flex;
    justify-content: space-between;
    align-items: center;

    h2 {
      margin: 0;
      color: #303133;
    }

    .header-actions {
      display: flex;
      gap: 10px;
      align-items: center;
    }
  }

  .playground-content {
    flex: 1;
    display: flex;
    gap: 20px;
    padding: 20px;
    overflow: hidden;

    .preview-panel {
      width: 650px;
      display: flex;
      flex-direction: column;
      gap: 15px;

      .preview-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 10px;
        background-color: #f5f7fa;
        border-radius: 4px;

        h3 {
          margin: 0;
          color: #303133;
          font-size: 16px;
        }
      }

      .canvas-container {
        background-color: #000;
        border-radius: 4px;
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 10px;

        canvas {
          border: 1px solid #dcdfe6;
          max-width: 100%;
          height: auto;
        }
      }
    }
  }
}
</style>

